﻿using System;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web;
using Liger.Data; 
using Liger.Common.Extensions;
using System.Data.Common;

using EasyFMS.Model;

namespace EasyFMS.Common
{
    /// <summary>
    /// 对DbContext类扩展一下 前台使用的常用方法
    /// </summary>
    public static class DbContextExtension
    {
        /// <summary>
        /// 获取 omGrid 所需要的JSON
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetOmGridJSON(this DbContext dbContext, HttpContext context)
        {
            string json = string.Empty;
            try
            {
                var bulider = GridDataBuliderProvider.Create(dbContext);
                string viewS = context.Request["view"];                                                                //数据源
                PageSort mySort = new PageSort(context.Request["sortby"], context.Request["sortdir"]);                 //排序
                PageView pageView = new PageView(context.Request["start"].ToInt(), context.Request["limit"]);     //分页
                string whereC = context.Request["where"];
                var data = bulider.GetGridData(viewS, whereC, mySort.Field, mySort.SortType, pageView.PageIndex, pageView.PageSize);
                string result = new Liger.Common.JSON.DataTableJSONSerializer().Serialize(data.Rows);
                json = @"{""rows"":" + result + @",""total"":" + data.Total + @"}";
            }
            catch (Exception ss)
            {
                json =  @"{""rows"":[],""total"":0}";
            }
            return json;
        }

        /// <summary>
        /// 获取通用选择窗的配置数据
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public static AjaxResult GetCommonSelectJSOM(this DbContext dbContext, HttpContext context)
        {
            string code = context.Request["code"];
            try
            {
                var metaDataEntity = dbContext.From<tMetaData>().Where(tMetaData._.Code == code).ToFirst();
                metaDataEntity.Attach();
                var fieldCode = metaDataEntity.FieldCode.Split(",");
                var fieldWidth = metaDataEntity.FieldWidth.Split(",");
                var fieldName = metaDataEntity.FieldName.Split(",");
                ArrayList colField = new ArrayList();
                if (fieldCode.Length == fieldName.Length && fieldName.Length == fieldWidth.Length)
                {
                    colField.Clear();
                    for (int i = 0, l = fieldCode.Length; i < l; i++)
                    {
                        colField.Add(new { header = fieldName[i].ToString(), name = fieldCode[i].ToString(), width = fieldWidth[i].ToString(), align = "center" });
                    }
                    var field = new
                    {
                        findField = metaDataEntity.FieldFind,
                        exportField = metaDataEntity.FieldExport,
                        dataField = colField,
                        sqlField = metaDataEntity.TSQL.Replace("\r\n"," "),
                        name = metaDataEntity.Name
                    };
                    return AjaxResult.Success(field, "OK");
                }
                else
                {
                    return AjaxResult.Error("字段编码,字段名称数目不匹配");
                }
            }
            catch (Exception aa)
            {
                return AjaxResult.Error(aa.Message);
            }
        }

        /// <summary>
        /// 获取 ligerTree 所需要的JSON
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetTreeJSON(this DbContext dbContext, HttpContext context)
        {
            string view = context.Request["view"];
            string where = context.Request["where"];
            string idfield = context.Request["idfield"];
            string pidfield = context.Request["pidfield"];
            string textfield = context.Request["textfield"];
            string iconfield = context.Request["iconfield"];
            string iconroot = context.Request["iconroot"] ?? "";
            string root = context.Request["root"];
            string rooticon = context.Request["rooticon"];
            string sql = "select {0} from [{1}] where {2}";

            string sqlselect = "[" + textfield + "] as [text]";
            if (iconfield.HasValue())
            {
                sqlselect += ",'" + iconroot + "'+[" + iconfield + "] as [icon]";
            }
            if (idfield.HasValue())
            {
                sqlselect += ",[" + idfield + "] as [id]";
            }
            if (idfield.HasValue())
            {
                sqlselect += ",[" + idfield + "]";
            }
            if (pidfield.HasValue())
            {
                sqlselect += ",[" + pidfield + "]";
            }

            sql = sql.FormatWith(sqlselect, view, where.IsNullOrEmpty() ? " 1=1 " : where);
            //创建command
            var cmd = CreateCommand(dbContext, sql);
            //使用liger.Data内置的数据适配器预处理command
            //比如对整数类型、日期类型的处理
            dbContext.Db.DbProvider.PrepareCommand(cmd);
            //获取树格式对象的JSON，这个方法首先会执行command，并且对结果进行格式化(转化为树格式)
            string json = JSONHelper.GetArrayJSON(cmd, idfield, pidfield);

            if (!root.IsNullOrEmpty())
            {
                json = @"[{""text"":""" + root + @""",""children"":" + json;
                if (rooticon.HasValue()) json += @",""icon"":""" + rooticon + @"""";
                json += "}]";
            }

            return json;
        }

        /// <summary>
        /// 获取menu所需要的JSON
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetMenuJSON(this DbContext dbContext, HttpContext context)
        {
            string json = @"[{""$ERROR$"":""菜单获取失败,请重新登录加载""}]";
            try
            {
                string cmdText = @"SELECT ModuleAlias,IsFolder,ParentID,Seq,ModuleTreeUID,URL FROM tModuleTree" +
                                " WHERE ModuleTreeUID IN (SELECT DISTINCT(ParentID) FROM vRightUserModule WHERE ModuleVerb = '打开' AND UserID = {0}) AND ((ParentID = 0) OR (ISNULL(URL,'') <> '')) " +
                                " UNION SELECT MAX(ModuleAlias),1,MAX(ParentID),MAX(Seq),MAX(ModuleTreeUID),MAX(URL) FROM vRightUserModule WHERE ModuleVerb = '打开' AND UserID = {1} AND ((ParentID = 0) OR (ISNULL(URL,'') <> '')) GROUP BY ModuleTreeUID Order by Seq";
                cmdText = cmdText.FormatWith(SysContext.CurrentUserID, SysContext.CurrentUserID);
                var menuSet = dbContext.ExecuteDataSet(cmdText);
                if (menuSet != null && menuSet.Tables[0].Rows.Count > 0)
                {
                    json = @"[";
                    var menuTable = menuSet.Tables[0];
                    int count = 1;
                    foreach (DataRow dr in menuTable.Select(" IsFolder=1 AND ParentID=0 "))
                    {
                        StringBuilder tempJson = new StringBuilder();
                        tempJson.Length = 0;
                        tempJson.Append(@"{""id"":""nav-panel-" + count.ToString() + @""",""menuid"":""" + dr["ModuleTreeUID"].ToString() + @""", ""title"":""" + dr["ModuleAlias"].ToString() + @""", ""mClass"": ""nav-panel"",");
                        DataRow[] tempDiv = menuTable.Select(" IsFolder=0 AND ParentID= '" + dr["ModuleTreeUID"].ToString() + "'");
                        tempJson.Append(@"""content"":[");
                        if (tempDiv.Length >= 1)
                        {
                            int tempDivCount = 1;
                            foreach (DataRow vdr in tempDiv)
                            {
                                tempJson.Append(@"{""id"":""nav-item-" + count.ToString() + "-" + tempDivCount.ToString() + @""",""menuid"":""" + vdr["ModuleTreeUID"].ToString() + @""", ""title"":""" + vdr["ModuleAlias"].ToString() + @""", ""mClass"": ""nav-item"",""url"":""" + vdr["URL"].ToString() + @"""},");
                                tempDivCount++;
                            }
                            tempJson = tempJson.Remove(tempJson.Length - 1, 1);
                        }
                        tempJson.Append(@"],");
                        DataRow[] tempTree = menuTable.Select(" IsFolder=1 AND ParentID= '" + dr["ModuleTreeUID"].ToString() + "'");
                        if (tempTree.Length >= 1)
                        {
                            tempJson.Append(@"""treeId"":""navtree-" + count.ToString() + @""",""treeContent"":[");
                            string ttC = GetomTreeInfo(tempTree, menuTable);
                            tempJson.Append(ttC.Remove(ttC.Length - 1, 1));
                            tempJson.Append(@"]},");
                        }
                        else
                        {
                            tempJson.Append(@"""treeId"":"""",""treeContent"":[]},");
                        }
                        count++;
                        json += tempJson.ToString();
                    }
                    json = json.Remove(json.Length - 1, 1).ToString() + "]";
                }
            }
            catch (Exception ss)
            {
                json = @"[{""$ERROR$"":""菜单获取失败,请重新登录加载""}]";
            }
            return json;
        }

        /// <summary>
        /// 递归获取树
        /// </summary>
        /// <param name="treeRow"></param>
        /// <returns></returns>
        public static string GetomTreeInfo(DataRow[] treeRow,DataTable sourceTable)
        {
            string treeJson = string.Empty;
            foreach (DataRow treeR in treeRow)
            {
                if (treeR["IsFolder"].ToString() == "True")
                {
                    treeJson += @"{""id"":""" + treeR["ModuleTreeUID"].ToString() + @""", ""text"":""" + treeR["ModuleAlias"].ToString() + @""",""pid"":""0""},";
                    treeJson += GetomTreeInfo(sourceTable.Select(" ParentID= '" + treeR["ModuleTreeUID"].ToString() + "'"), sourceTable);
                }
                else
                {
                    treeJson += @"{""id"":""" + treeR["ModuleTreeUID"].ToString() + @""",""pid"":""" + treeR["ParentID"].ToString() + @""", ""text"":""" + treeR["ModuleAlias"].ToString() + @""",""url"":""" + treeR["URL"].ToString() + @"""},";
                }
            }
            return treeJson;
        }


        /// <summary>
        /// 获取 ligerGrid(Tree) 所需要的JSON
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetGridTreeJSON(this DbContext dbContext, HttpContext context)
        {
            string view = context.Request["view"];
            string where = context.Request["where"];
            string idfield = context.Request["idfield"];
            string pidfield = context.Request["pidfield"]; 
            string sql = "select * from [{0}] where {1}";

            sql = sql.FormatWith(view, where.IsNullOrEmpty() ? " 1=1 " : where);
            //创建command
            var cmd = CreateCommand(dbContext, sql);
            //使用liger.Data内置的数据适配器预处理command
            //比如对整数类型、日期类型的处理
            dbContext.Db.DbProvider.PrepareCommand(cmd);
            //获取树格式对象的JSON，这个方法首先会执行command，并且对结果进行格式化(转化为树格式)
            List<Hashtable> o = JSONHelper.ArrayToTreeData(cmd, idfield, pidfield) as List<Hashtable>;
           
            string json = @"{""Rows"":" + JSONHelper.ToJson(o) + @",""Total"":""" + o.Count + @"""}";
            return json;
        }

        /// <summary>
        /// 获取 ligerComboBox 所需要的JSON
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetSelectJSON(this DbContext dbContext, HttpContext context)
        {
            string view = context.Request["view"];
            string where = context.Request["where"];
            string idfield = context.Request["idfield"];
            string textfield = context.Request["textfield"];
            string distinct = context.Request["distinct"];
            string sql = "select "
                + ((distinct.HasValue() && distinct != "false") ? "distinct" : "")
                + @"  {0} from [{1}] where {2}";
            var sqlselect = "";
            if (idfield.HasValue())
            {
                sqlselect += ",[" + idfield + "] as [id]";
                sqlselect += ",[" + idfield + "] as [value]";
            }
            if (textfield.HasValue())
            {
                sqlselect += ",[" + textfield + "] as [text]";
            }
            
            sql = sql.FormatWith(sqlselect.HasValue() ? sqlselect.Substring(1) : "*", view, where.IsNullOrEmpty() ? " 1=1 " : where);
            //创建command
            var cmd = CreateCommand(dbContext, sql);
            //使用liger.Data内置的数据适配器预处理command
            //比如对整数类型、日期类型的处理
            dbContext.Db.DbProvider.PrepareCommand(cmd);
            var ds = dbContext.ExecuteDataSet(cmd);
            var json = new Liger.Common.JSON.DataSetJSONSerializer().Serialize(ds);
            return json;
        }

        /// <summary>
        /// 获取 ComboBox 所需要的JSON
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetComboxJSON(this DbContext dbContext, HttpContext context)
        {
            string type = context.Request["type"];
            string sql = "SELECT [UID],[Code],[Name],[Type],[SeqNo] FROM [dbo].[vBaseData] ORDER BY [UID],[SeqNo]";
            switch (type)
            {
                case "other":
                    sql = context.Request["view"];
                    break;
                default:
                    break;
            }
            var cmd = CreateCommand(dbContext, sql);
            dbContext.Db.DbProvider.PrepareCommand(cmd);
            var ds = dbContext.ExecuteDataSet(cmd);
            var json = new Liger.Common.JSON.DataSetJSONSerializer().Serialize(ds);
            return json;
        }

        private static DbCommand CreateCommand(DbContext dbContext, string commandText)
        {
            var DbProvider = dbContext.Db.DbProvider;
            var cmd = DbProvider.DbProviderFactory.CreateCommand();
            cmd.CommandText = commandText;
            //if (parms != null)
            //{
            //    foreach (var parm in parms)
            //    {
            //        DbParameter p = DbProvider.DbProviderFactory.CreateParameter();
            //        p.ParameterName = DbProvider.ParamPrefix + parm.Name;
            //        p.Value = parm.Value;
            //        cmd.Parameters.Add(p);
            //    }
            //}
            return cmd;
        }

        /// <summary>
        /// 获取实体对象，并返回对前台友好的数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dbContext"></param>
        /// <param name="exp"></param>
        /// <returns></returns>
        public static AjaxResult GetEntity<T>(this DbContext dbContext, WhereExpression exp)
          where T : Entity
        {
            try
            {
                var result = dbContext.From<T>().Where(exp).ToFirst();
                if (result == null)
                {
                    return AjaxResult.Error("加载失败");
                }
                else
                {
                    return AjaxResult.Success(result, "加载成功");
                }
            }
            catch (Exception err)
            {
                return AjaxResult.Error("系统错误:" + err.Message);
            }
        }

        /// <summary>
        /// 插入实体对象，并返回对前台友好的数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dbContext"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static AjaxResult InsertEntity<T>(this DbContext dbContext, T entity)
            where T : Entity
        {
            try
            {
                var result = dbContext.Insert<T>(entity);
                return AjaxResult.Success(result, "保存成功");

            }
            catch (Exception err)
            {
                LogManager.WriteLog("Error", err.Message);
                return AjaxResult.Error("系统错误:" + err.Message);
            }
        }

        /// <summary>
        /// 保存实体对象，并返回对前台友好的数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dbContext"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static AjaxResult UpdateEntity<T>(this DbContext dbContext, T entity)
           where T : Entity
        {
            try
            {
                var result = dbContext.Update<T>(entity);
                return AjaxResult.Success(result, "保存成功");
            }
            catch (Exception err)
            {
                LogManager.WriteLog("Error", err.Message);
                return AjaxResult.Error("系统错误:" + err.Message);
            }
        }

        /// <summary>
        /// 删除实体对象，并返回对前台友好的数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dbContext"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static AjaxResult DeleteEntity<T>(this DbContext dbContext, T entity)
           where T : Entity
        {
            try
            {
                var result = dbContext.Delete<T>(entity);
                return AjaxResult.Success(result, "删除成功");

            }
            catch (Exception err)
            {
                LogManager.WriteLog("Error", err.Message);
                return AjaxResult.Error("系统错误:" + err.Message);
            }
        }

        /// <summary>
        /// 删除实体对象，并返回对前台友好的数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dbContext"></param>
        /// <param name="pkValue"></param>
        /// <returns></returns>
        public static AjaxResult DeleteEntity<T>(this DbContext dbContext, string pkValue)
           where T : Entity
        {
            try
            {
                var result = dbContext.Delete<T>(pkValue);
                return AjaxResult.Success(result, "删除成功");

            }
            catch (Exception err)
            {
                LogManager.WriteLog("Error", err.Message);
                return AjaxResult.Error("系统错误:" + err.Message);
            }
        }


    }
}